:art: Support AdministratorInfo and relation

FFIB 5 gadi atpakaļ
vecāks
revīzija
d1f2463a76

+ 19 - 1
account/admin.py

@@ -1,12 +1,30 @@
1 1
 # -*- coding: utf-8 -*-
2 2
 
3 3
 from django.contrib import admin
4
+from django.contrib.auth.hashers import make_password
5
+from django.conf import settings
4 6
 
5
-from account.models import UserInfo
7
+from pysnippets.strsnippets import strip
8
+
9
+from account.models import UserInfo, AdministratorInfo
6 10
 
7 11
 
8 12
 class UserInfoAdmin(admin.ModelAdmin):
9 13
     list_display = ('user_id', 'unionid', 'openid', 'nickname', 'sex', 'avatar', 'phone', 'country', 'province', 'city', 'status', 'created_at', 'updated_at')
10 14
 
15
+class AdministratorInfoAdmin(admin.ModelAdmin):
16
+    list_display = ('admin_id', 'admin_type', 'password', 'encryption', 'name', 'user_status', 'status', 'created_at', 'updated_at')
17
+    list_filter = ('admin_type', 'user_status', 'status')
18
+    readonly_fields = ('encryption',)
19
+
20
+    def save_model(self, request, obj, form, change):
21
+        obj.phone = strip(obj.name)
22
+        obj.password = strip(obj.password)
23
+        if obj.password:
24
+            obj.encryption = make_password(obj.password, settings.MAKE_PASSWORD_SALT, settings.MAKE_PASSWORD_HASHER)
25
+        obj.password = ''
26
+        obj.save()
27
+
11 28
 
12 29
 admin.site.register(UserInfo, UserInfoAdmin)
30
+admin.site.register(AdministratorInfo, AdministratorInfoAdmin)

+ 33 - 0
account/migrations/0003_administratorinfo.py

@@ -0,0 +1,33 @@
1
+# Generated by Django 2.2.12 on 2020-04-26 09:31
2
+
3
+from django.db import migrations, models
4
+import shortuuidfield.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('account', '0002_auto_20200426_1624'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='AdministratorInfo',
16
+            fields=[
17
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')),
19
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
20
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
21
+                ('admin_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='管理员唯一标识', max_length=22, null=True, unique=True)),
22
+                ('admin_type', models.IntegerField(choices=[(0, '管理员')], db_index=True, default=0, help_text='管理员类型', verbose_name='admin_type')),
23
+                ('name', models.CharField(blank=True, help_text='管理员名称', max_length=255, null=True, verbose_name='name')),
24
+                ('password', models.CharField(blank=True, help_text='管理员密码', max_length=255, null=True, verbose_name='password')),
25
+                ('encryption', models.CharField(blank=True, help_text='管理员密码', max_length=255, null=True, verbose_name='encryption')),
26
+                ('user_status', models.IntegerField(choices=[(1, '已激活'), (2, '已禁用'), (3, '已删除')], db_index=True, default=1, help_text='管理员状态', verbose_name='user_status')),
27
+            ],
28
+            options={
29
+                'verbose_name': '管理员信息',
30
+                'verbose_name_plural': '管理员信息',
31
+            },
32
+        ),
33
+    ]

+ 34 - 0
account/models.py

@@ -56,3 +56,37 @@ class UserInfo(BaseModelMixin):
56 56
             'nickname': self.nickname,
57 57
             'avatar': self.avatar,
58 58
         }
59
+
60
+class AdministratorInfo(BaseModelMixin):
61
+    ADMINISTRATOR = 0
62
+
63
+    USER_TYPE_TUPLE = (
64
+        (ADMINISTRATOR, u'管理员'),
65
+    )
66
+
67
+    ACTIVATED = 1
68
+    DISABLED = 2
69
+    DELETED = 3
70
+
71
+    USER_STATUS_TUPLE = (
72
+        (ACTIVATED, u'已激活'),
73
+        (DISABLED, u'已禁用'),
74
+        (DELETED, u'已删除'),
75
+    )
76
+
77
+    admin_id = ShortUUIDField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'管理员唯一标识', db_index=True, unique=True)
78
+
79
+    admin_type = models.IntegerField(_(u'admin_type'), choices=USER_TYPE_TUPLE, default=ADMINISTRATOR, help_text=u'管理员类型', db_index=True)
80
+
81
+    name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'管理员名称')
82
+    password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'管理员密码')
83
+    encryption = models.CharField(_(u'encryption'), max_length=255, blank=True, null=True, help_text=u'管理员密码')
84
+
85
+    user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS_TUPLE, default=ACTIVATED, help_text=u'管理员状态', db_index=True)
86
+
87
+    class Meta:
88
+        verbose_name = _(u'管理员信息')
89
+        verbose_name_plural = _(u'管理员信息')
90
+
91
+    def __unicode__(self):
92
+        return u'{}-{}'.format(self.name, self.phone)

+ 42 - 1
api/admin_views.py

@@ -6,20 +6,50 @@ from django.conf import settings
6 6
 from django.db import transaction
7 7
 from django_logit import logit
8 8
 from django_response import response
9
+from django.contrib.auth.hashers import check_password
9 10
 from django.db.models import Q
10 11
 
11 12
 from TimeConvert import TimeConvert as tc
12 13
 
13
-from account.models import UserInfo
14
+from account.models import UserInfo, AdministratorInfo
14 15
 from goods.models import GoodsInfo, PackInfo
15 16
 from kol.models import KOLInfo
16 17
 from pay.models import OrderInfo
17 18
 
19
+from utils.error.errno_utils import AdministratorStatusCode
20
+
18 21
 logger = logging.getLogger('logit')
19 22
 
20 23
 @logit(res=True)
24
+def login(request):
25
+    name = request.POST.get('name', '')
26
+    password = request.POST.get('password', '')
27
+
28
+    try:
29
+        administrator = AdministratorInfo.objects.get(name=name, status=True)
30
+    except AdministratorInfo.DoesNotExist:
31
+        return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)
32
+
33
+    if administrator.user_status == AdministratorInfo.DISABLED:
34
+        return response(AdministratorStatusCode.ADMINISTRATOR_NOT_ACTIVATED)
35
+    elif administrator.user_status == AdministratorInfo.DELETED:
36
+        return response(AdministratorStatusCode.ADMINISTRATOR_HAS_DELETED)
37
+
38
+    if not check_password(password, administrator.encryption):
39
+        return response(AdministratorStatusCode.ADMINISTRATOR_PASSWORD_ERROR)
40
+
41
+    request.session['admin_id'] = administrator.admin_id
42
+
43
+    return response(200, 'Admin Login Success', u'管理员登录成功', data={
44
+        'admin_id': administrator.admin_id,
45
+        'admin_type': administrator.admin_type,
46
+    })
47
+
48
+
49
+@logit(res=True)
21 50
 @transaction.atomic
22 51
 def order_list(request):
52
+  admin_id = request.POST.get('admin_id', '')
23 53
   kol_id = request.POST.get('kol_id', '')
24 54
   pack_id = request.POST.get('pack_id', '')
25 55
   ftime = request.POST.get('ftime', '')
@@ -29,6 +59,11 @@ def order_list(request):
29 59
   page = request.POST.get('page', 0)
30 60
   num = request.POST.get('num', 20)
31 61
 
62
+  try:
63
+    administrator = AdministratorInfo.objects.get(admin_id=admin_id, user_status=AdministratorInfo.ACTIVATED, status=True)
64
+  except AdministratorInfo.DoesNotExist:
65
+    return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)
66
+
32 67
   infos = OrderInfo.objects.filter(Q(phone__contains=query) | Q(name__contains=query) & Q(kol_id__contains=kol_id) & Q(pack_id__contains=pack_id)& Q(pay_status=1))
33 68
 
34 69
   res = []
@@ -71,10 +106,16 @@ def order_list(request):
71 106
 @logit(res=True)
72 107
 @transaction.atomic
73 108
 def order_update(request):
109
+    admin_id = request.POST.get('admin_id', '')
74 110
     order_id = request.POST.get('order_id', '')
75 111
     tracking_number = request.POST.get('tracking_number', '')
76 112
 
77 113
     try:
114
+      administrator = AdministratorInfo.objects.get(admin_id=admin_id, user_status=AdministratorInfo.ACTIVATED, status=True)
115
+    except AdministratorInfo.DoesNotExist:
116
+      return response(AdministratorStatusCode.ADMINISTRATOR_NOT_FOUND)
117
+
118
+    try:
78 119
       order = OrderInfo.objects.get(order_id=order_id)
79 120
       order.tracking_number = tracking_number
80 121
       order.save()

+ 2 - 0
api/urls.py

@@ -21,6 +21,8 @@ urlpatterns += [
21 21
 ]
22 22
 
23 23
 urlpatterns += [
24
+    url(r'^admin/login$', admin_views.login, name='login'),
25
+
24 26
     url(r'^admin/order/list$', admin_views.order_list, name='order_list'),   # 订单列表
25 27
     url(r'^admin/order/update$', admin_views.order_update, name='order_update'),   # 订单列表
26 28
 ]

+ 1 - 0
requirements.txt

@@ -3,6 +3,7 @@ furl==2.1.0
3 3
 jsonfield==2.0.2
4 4
 mysqlclient==1.4.6
5 5
 rlog==0.3
6
+pysnippets==1.1.2
6 7
 -r requirements_dj.txt
7 8
 -r requirements_pywe.txt
8 9
 -r requirements_redis.txt

+ 11 - 0
utils/error/errno_utils.py

@@ -2,6 +2,17 @@
2 2
 
3 3
 from StatusCode import BaseStatusCode, StatusCodeField
4 4
 
5
+class AdministratorStatusCode(BaseStatusCode):
6
+    """ 操作员相关错误码 4002xx """
7
+    ADMINISTRATOR_NOT_FOUND = StatusCodeField(400201, 'Administrator Not Found', description=u'管理员不存在')
8
+    # 密码
9
+    ADMINISTRATOR_PASSWORD_ERROR = StatusCodeField(400202, 'Administrator Password Error', description=u'管理员密码错误')
10
+    # 用户名
11
+    ADMINISTRATOR_NAME_ALREADY_EXISTS = StatusCodeField(400205, 'Administrator Name Already Exists', description=u'管理员手机号已经存在')
12
+    # 状态
13
+    ADMINISTRATOR_NOT_ACTIVATED = StatusCodeField(400215, 'Administrator Not Activated', description=u'管理员未激活')
14
+    ADMINISTRATOR_HAS_DISABLED = StatusCodeField(400216, 'Administrator Has Disabled', description=u'管理员已禁用')
15
+    ADMINISTRATOR_HAS_DELETED = StatusCodeField(400217, 'Administrator Has Deleted', description=u'管理员已删除')
5 16
 
6 17
 class ParamStatusCode(BaseStatusCode):
7 18
     """ 4000xx 参数相关错误码 """